<?php

namespace App\Repositories;


use App\Exceptions\BasicException;
use App\Services\Tools\CommonService;
use Illuminate\Support\Facades\DB;
use App\Enums\ErmEnum;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use App\Enums\RedisKeyEnum;

//引入hash

class ErmGrayRepository
{

    /*自动加灰*/
    public function autoAddGray()
    {
        /*自动加灰(同一个账号出现三个及以上微信open_id，支付宝buyer_id)*/
        $this->grayCheckPayId();
        /*自动加灰(没有收益/充值进行消费)*/
        $this->grayCheckStatisticAmount();
    }

    /*自动加灰(同一个账号出现三个及以上微信open_id，支付宝buyer_id)*/
    public function grayCheckPayId($interval_time = 86400)
    {
        $start_time=time()-$interval_time;
        $end_time=time();
        $last_erm_pay_id_res = app("model_erm_pay_id_record")->select('id')->where([['create_time', '>=', $start_time], ['create_time', '<=', $end_time]])->orderBy('id', 'desc')->first();
        if (!$last_erm_pay_id_res) {
            return true;
        }

        $erm_pay_id_res = app("model_erm_pay_id_record")
            ->selectRaw('user_id,count(distinct pay_id) as pay_id_num,type')
            ->with('erm_public_list:user_id,type')
            ->where([['create_time', '>=', $start_time], ['create_time', '<=', $end_time]])
            ->groupBy('user_id')
            ->groupBy('type')
            ->get()->toArray();
        if (!$erm_pay_id_res) {
            return true;
        }

        /*风控规则*/
        $wx_rule = $this->getConfig(ErmEnum::USER_WX_PAY_OPEN_ID_LIMIT);
        $ali_rule = $this->getConfig(ErmEnum::USER_ALI_PAY_BUYER_ID_LIMIT);

        /*加锁防止并发造成数据混乱，如果程序运行超时，锁定200秒*/
        $lock_second = 200;
        $lock_key = RedisKeyEnum::ERM_GRAY_CHECK_PAY_LOCK;
        $lock = Redis::setnx($lock_key, 1);
        if (!$lock) {
            throw new BasicException(100004);
        }
        Redis::expire($lock_key, $lock_second);

        DB::beginTransaction();
        try {
            /*24小时有被移出记录，排除自动加灰*/
            $erm_list_record_res = app("model_erm_list_record")->select('user_id')->where(['old_type'=>3,'new_type'=>1,['create_time', '>=', $start_time], ['create_time', '<=', $end_time]])->pluck('user_id')->toArray();
            foreach ($erm_pay_id_res as $k => $v) {
                $type = $v['erm_public_list']['type'] ?? 1;
                if (!in_array($type, [ErmEnum::PUBLIC_TYPE,ErmEnum::WHITE_TYPE])) {
                    continue;
                }
                /*24小时有被移出记录，排除自动加灰*/
                if (in_array($v['user_id'], $erm_list_record_res)) {
                    continue;
                }
                /*单人微信open_id可持有数量上限*/
                if ($v['type'] == 1 && !empty($wx_rule) && $v['pay_id_num'] > $wx_rule['value']) {
                    if ($type == ErmEnum::PUBLIC_TYPE) {
                        app('repo_erm_public_list')->joinListWay($v['user_id'], ErmEnum::GRAY_TYPE, '自动加灰:多个微信支付id');
                    }
                    if ($type == ErmEnum::WHITE_TYPE) {
                        app('repo_erm_white')->triggerLimit($v['user_id']);
                    }
                }
                /*单人支付宝buyer_id可持有数量上限*/
                if ($v['type'] == 2 && !empty($ali_rule) && $v['pay_id_num'] > $ali_rule['value']) {
                    $public_list_res = app("model_erm_public_list")->where(['user_id' => $v['user_id']])->first();
                    if ($public_list_res['type'] == ErmEnum::PUBLIC_TYPE) {
                        app('repo_erm_public_list')->joinListWay($v['user_id'], ErmEnum::GRAY_TYPE, '自动加灰:多个支付宝支付id');
                    }
                    if ($type == ErmEnum::WHITE_TYPE) {
                        app('repo_erm_white')->triggerLimit($v['user_id']);
                    }
                }
            }

            /*解锁*/
            Redis::del($lock_key);

            DB::commit();

        } catch (\Exception $e) {
            DB::rollBack();
            throw new BasicException(100003, $e->getMessage());
        }

        return true;
    }

    private function getConfig($key)
    {
        $rule = app('model_erm_config')->where([
            'status' => 0,
            'key' => $key,
        ])->first();

        return $rule;
    }

    /*自动加灰(没有任何收益/充值且进行消费)*/
    public function grayCheckStatisticAmount($time = 300)
    {
        /*排除的名单*/
        $exclude_list = app("model_erm_public_list")->select('user_id')->whereIn('type', [3, 4])->pluck('user_id')->toArray();
        $white_list = app("model_erm_public_list")->select('user_id')->whereIn('type', [2])->pluck('user_id')->toArray();
        /*消费用户*/
        $consume_start_time = time() - $time;
        $consume_user_res = app("model_erm_statistic_amount")->where([['last_consume_time', '>=', $consume_start_time]])->pluck('user_id')->toArray();
        $consume_user_res = array_diff($consume_user_res, $exclude_list);
        if (!$consume_user_res) {
            return true;
        }

        /*没有收益用户*/
        $earnings_user_res = app("model_erm_statistic_amount")->whereIn('user_id', $consume_user_res)->where([['earnings_num', '>', 0]])->pluck('user_id')->toArray();
        /*没有充值用户*/
        $recharge_user_res = app("model_erm_public_list")->whereIn('user_id', $consume_user_res)->where([['recharge_num', '>', 0]])->pluck('user_id')->toArray();
        $diff_user_id = array_diff($consume_user_res, $earnings_user_res, $recharge_user_res);
        /*添加大众名单用户*/
        $add_user_id = $diff_user_id;
        if ($add_user_id) {
            $add_data = [];
            $user_res = app("model_user")->select('user_id', 'register_time')->whereIn('user_id', $add_user_id)->get()->keyBy('user_id')->toArray();

            DB::beginTransaction();
            try {
                /*不在大众名单就添加大众名单用户*/
                foreach ($add_user_id as $k => $v) {
                    $isHavePublicList = app("model_erm_public_list")->where('user_id', $v)->first();
                    if (empty($isHavePublicList)) {
                        $add_data[] = [
                            'user_id'       => $v,
                            'register_time' => $user_res[$v]['register_time'] ?? 0,
                            'create_time'   => time(),
                        ];
                    }
                }
                if (!empty($add_data)) {
                    $add_res = app("model_erm_public_list")->insert($add_data);
                    if (!$add_res) {
                        throw new BasicException(100005);
                    }
                }

                foreach ($add_user_id as $k => $v) {
                    if (in_array($v, $white_list)) {
                        app('repo_erm_white')->triggerLimit($v);
                    } else {
                        app('repo_erm_public_list')->joinListWay($v, ErmEnum::GRAY_TYPE, '自动加灰:没有收益/充值进行消费');
                    }
                }

                DB::commit();

            } catch (\Exception $e) {
                DB::rollBack();
                throw new BasicException(100005, $e->getMessage());
            }
        }
    }

    /**
     * 灰名单移除记录
     *
     * @param array $params
     * @param int $page
     * @param int $perPage
     * @return mixed
     */
    public function removeGrayListLog($params, $page, $perPage)
    {
        $where = [];

        if (isset($params['user_code'])) {
            $where[] = ['t3.user_code', '=',  $params['user_code']];
        }

        if (isset($params['nickname'])) {
            $where[] = ['t3.nickname', '=',  $params['nickname']];
        }

        if (isset($params['user_type'])) {
            $where[] = ['t2.user_type', '=',  $params['user_type']];
        }

        if (isset($params['operator_id'])) {
            $where[] = ['t1.operator_id', '=',  $params['operator_id']];
        }

        if (isset($params['new_type'])) {
            $where[] = ['t1.new_type', '=',  $params['new_type']];
        }

        if (isset($params['register_start_time'])) {
            $where[] = ['t2.register_time', '>=',  strtotime($params['register_start_time'])];
        }

        if (isset($params['register_end_time'])) {
            $where[] = ['t2.register_time', '<=',  strtotime($params['register_end_time'])];
        }

        if (isset($params['remove_start_time'])) {
            $where[] = ['t1.create_time', '>=',  strtotime($params['remove_start_time'])];
        }

        if (isset($params['remove_end_time'])) {
            $where[] = ['t1.create_time', '<=',  strtotime($params['remove_end_time'])];
        }
        $fields = [
            't1.id',
            't1.user_id',
            't1.new_type',
            't1.operator_id',
            't1.create_time as remove_time',
            't1.remark',
            't2.user_type',
            't2.register_time',
            't3.user_code',
            't3.nickname',
            't4.admin_name'
        ];
        $recordModel = app('model_erm_list_record');
        $publicListModel = app("model_erm_public_list");
        $userDataModel = app('model_user_data');
        $adminModel = app('model_admin');

        $list = app('model_erm_list_record')
            ->from($recordModel->getTable() . " as t1")
            ->leftJoin(DB::raw($publicListModel->getTable() . " as t2"), "t1.user_id", "=", "t2.user_id")
            ->leftJoin(DB::raw($userDataModel->getTable() . " as t3"), "t1.user_id", "=", "t3.user_id")
            ->leftJoin(DB::raw($adminModel->getTable() . " as t4"), "t1.operator_id", "=", "t4.admin_id")
            ->where($where)
            ->where('t1.old_type', ErmEnum::GRAY_TYPE)
            ->select($fields)
            ->orderBy('t1.id', 'desc')
            ->paginate($perPage, ['*'], '', $page)
            ->toArray();

        $data = [];
        foreach ($list['data'] as $v) {
            $reason = $remark = '';
            if ($v['remark']) {
                if (strpos($v['remark'], ':') !== false) {
                    list($reason, $remark) = explode(':', $v['remark']);
                }
                if (strpos($v['remark'], '：') !== false) {
                    list($reason, $remark) = explode('：', $v['remark']);
                }
                if (empty($reason)){
                    $reason = $v['remark'];
                }
            }
            $data[] = [
                'id' => $v['id'],
                'user_code' => $v['user_code'],
                'nickname' => $v['nickname'],
                'new_type' => $v['new_type'],
                'user_type' => $v['user_type'],
                'register_time' => date('Y-m-d H:i:s', $v['register_time']),
                'remove_time' => date('Y-m-d H:i:s', $v['remove_time']),
                'reason' => $reason,
                'remark' => $remark,
                'operator_id' => $v['operator_id'],
                'operator_name' => $v['admin_name'] ?? '',
            ];
        }

        return [
            'data' => $data,
            'total' => $list['total'],
        ];
    }

}
